import tkinter as tk
from tkinter import filedialog, scrolledtext, messagebox, ttk
import re
import os

class LatexCiteConverterApp:
    def __init__(self, root):
        self.root = root
        self.root.title("LaTeX引用格式转换工具")
        self.root.geometry("800x600")

        self.create_widgets()

    def create_widgets(self):
        main_frame = ttk.Frame(self.root, padding=10)
        main_frame.pack(fill="both", expand=True)

        # 顶部说明
        header_frame = ttk.Frame(main_frame)
        header_frame.pack(fill="x", pady=(0, 15))

        ttk.Label(
            header_frame,
            text="本工具可将LaTeX文档中的\\cite{...}转换为\\textsuperscript{\\cite{...}}格式",
            font=("Helvetica", 11, "bold")
        ).pack(anchor="w")

        # 文件选择区域
        file_frame = ttk.LabelFrame(main_frame, text="文件选择", padding=10)
        file_frame.pack(fill="x", pady=10)

        # 文件列表
        file_list_frame = ttk.Frame(file_frame)
        file_list_frame.pack(fill="both", expand=True)

        self.file_list = tk.Listbox(file_list_frame, height=8, width=70, selectmode=tk.EXTENDED)
        scrollbar_y = ttk.Scrollbar(file_list_frame, orient="vertical", command=self.file_list.yview)
        scrollbar_x = ttk.Scrollbar(file_list_frame, orient="horizontal", command=self.file_list.xview)

        self.file_list.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)

        scrollbar_y.pack(side="right", fill="y")
        self.file_list.pack(side="top", fill="both", expand=True)
        scrollbar_x.pack(side="bottom", fill="x")

        # 文件操作按钮
        btn_frame = ttk.Frame(file_frame)
        btn_frame.pack(fill="x", pady=(10, 0))

        ttk.Button(btn_frame, text="添加文件", command=self.add_files).pack(side="left", padx=2)
        ttk.Button(btn_frame, text="删除所选", command=self.remove_files).pack(side="left", padx=2)
        ttk.Button(btn_frame, text="清空列表", command=self.clear_files).pack(side="left", padx=2)

        # 输出选项
        options_frame = ttk.LabelFrame(main_frame, text="输出选项", padding=10)
        options_frame.pack(fill="x", pady=15)

        self.output_var = tk.StringVar(value="create_new")

        ttk.Radiobutton(
            options_frame,
            text="创建新文件 (原文件名_converted.tex)",
            variable=self.output_var,
            value="create_new"
        ).pack(anchor="w", pady=2)

        ttk.Radiobutton(
            options_frame,
            text="覆盖原始文件",
            variable=self.output_var,
            value="overwrite"
        ).pack(anchor="w", pady=2)

        # 预览区域
        preview_frame = ttk.LabelFrame(main_frame, text="转换预览", padding=10)
        preview_frame.pack(fill="both", expand=True, pady=10)

        self.preview_text = scrolledtext.ScrolledText(preview_frame, height=10, wrap=tk.WORD)
        self.preview_text.pack(fill="both", expand=True)
        self.preview_text.insert(tk.END,
                                 "示例转换:\n\\cite{yang2019federated,liu2019communication}\n\n将转换为:\n\\textsuperscript{\\cite{yang2019federated,liu2019communication}}")
        self.preview_text.config(state="disabled")

        # 操作按钮
        action_frame = ttk.Frame(main_frame)
        action_frame.pack(fill="x", pady=15)

        ttk.Button(
            action_frame,
            text="开始转换",
            command=self.convert_files,
            style="Accent.TButton",
            padding=(10, 5)
        ).pack(side="right")

        # 设置样式
        style = ttk.Style()
        style.configure("Accent.TButton", font=("Helvetica", 10, "bold"))

        # 状态栏
        self.status_var = tk.StringVar(value="就绪")
        status_bar = ttk.Label(
            self.root,
            textvariable=self.status_var,
            relief="sunken",
            anchor="w",
            padding=(3, 2)
        )
        status_bar.pack(side="bottom", fill="x")

    def add_files(self):
        """添加文件到列表"""
        files = filedialog.askopenfilenames(
            title="选择LaTeX文件",
            filetypes=[("LaTeX文件", "*.tex"), ("所有文件", "*.*")]
        )

        if files:
            current_files = self.file_list.get(0, tk.END)
            for file in files:
                if file not in current_files:
                    self.file_list.insert(tk.END, file)

    def remove_files(self):
        """从列表中删除选中的文件"""
        selected = self.file_list.curselection()
        if not selected:
            return

        # 从后向前删除，避免索引变化
        for i in sorted(selected, reverse=True):
            self.file_list.delete(i)

    def clear_files(self):
        """清空文件列表"""
        self.file_list.delete(0, tk.END)

    def convert_files(self):
        """执行文件转换"""
        files = list(self.file_list.get(0, tk.END))

        if not files:
            messagebox.showerror("错误", "请先添加需要转换的文件")
            return

        output_mode = self.output_var.get()
        create_new = (output_mode == "create_new")

        self.status_var.set("正在转换文件...")
        self.root.update()

        success_count = 0
        error_files = []

        for file_path in files:
            try:
                # 读取文件内容
                with open(file_path, 'r', encoding='utf-8') as f:
                    content = f.read()

                # 转换引用格式，避免已经是textsuperscript的情况
                pattern = r'(?<!\\textsuperscript\{)\\cite\{([^\}]+)\}'
                converted = re.sub(pattern, r'\\textsuperscript{\\cite{\1}}', content)

                # 确定输出路径
                if create_new:
                    base, ext = os.path.splitext(file_path)
                    output_path = f"{base}_converted{ext}"
                else:
                    output_path = file_path

                # 写入新文件
                with open(output_path, 'w', encoding='utf-8') as f:
                    f.write(converted)

                success_count += 1

            except Exception as e:
                error_files.append((file_path, str(e)))

        # 显示结果
        if error_files:
            error_msg = "以下文件处理失败:\n\n"
            for file, err in error_files[:5]:  # 只显示前5个错误
                error_msg += f"• {os.path.basename(file)}: {err}\n"
            if len(error_files) > 5:
                error_msg += f"\n...共 {len(error_files)} 个文件出错"

            messagebox.showerror("转换出错", error_msg)

        if success_count > 0:
            if create_new:
                msg = f"成功转换 {success_count} 个文件，已创建新文件。"
            else:
                msg = f"成功转换 {success_count} 个文件，原文件已更新。"
            messagebox.showinfo("转换完成", msg)

        self.status_var.set(f"转换完成: {success_count}个成功, {len(error_files)}个失败")


def main():
    root = tk.Tk()
    app = LatexCiteConverterApp(root)
    root.mainloop()


if __name__ == "__main__":
    main()